package com.group1.bookmanagement.service.impl;

import java.io.File;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.stereotype.Service;

import com.group1.bookmanagement.dao.BaseDao;
import com.group1.bookmanagement.domain.Label;
import com.group1.bookmanagement.domain.PasswordChangedRecord;
import com.group1.bookmanagement.domain.Photo;
import com.group1.bookmanagement.domain.User;
import com.group1.bookmanagement.service.UserService;
import com.group1.bookmanagement.util.MailUtils;

@Service("userService")
public class UserServiceImpl implements UserService {
	
	@Resource(name = "baseDao")
	private BaseDao<User> userDao;
	@Resource(name = "baseDao")
	private BaseDao<Photo> photoDao;
	@Resource(name = "baseDao")
	private BaseDao<PasswordChangedRecord> passwordChangedRecordDao;

	@Override
	public void saveUser(User user) {
		Date date = new Date();
		user.setSex("男");
		user.setNickName(user.getUsername());
		user.setCreatedAt(date);
		user.setUpdatedAt(date);
		user.setBirthday(date);
		user.setAutoLoginCredential(UUID.randomUUID().toString());
		userDao.save(user);
	}

	@Override
	public void deleteUser(User user) {
		Photo avator = user.getAvator();
		if (avator != null) {
			avator.getFile().delete();
		}
		
		userDao.delete(user);
	}

	@Override
	public void updateUser(User user) {
		User user_previous = getUser(user.getId());
		//原来的头像
		Photo avator_previous = user_previous.getAvator();
		//修改后的头像
		Photo avator = user.getAvator();
		
		if (avator == null) {
			user.setAvator(avator_previous);
		} else {
			photoDao.save(avator);
		}
		
		Session session = userDao.openSession();
		session.beginTransaction();
		String hql = new StringBuilder("update User u set ")
				.append("u.remark = ?, ")
				.append("u.nickName = ?, ")
				.append("u.birthday = ?, ")
				.append("u.sex = ?, ")
				.append("u.phone = ?, ")
				.append("u.address = ?, ")
				.append("u.email = ?, ")
				.append("u.avator = ?, ")
				.append("u.updatedAt = ? ")
				.append("where id = ?")
				.toString();
		
		Query query = session.createQuery(hql);
		query.setParameter(0, user.getRemark());
		query.setParameter(1, user.getNickName());
		query.setParameter(2, user.getBirthday());
		query.setParameter(3, user.getSex());
		query.setParameter(4, user.getPhone());
		query.setParameter(5, user.getAddress());
		query.setParameter(6, user.getEmail());
		query.setParameter(7, user.getAvator());
		query.setParameter(8, new Date());
		query.setParameter(9, user.getId());
		query.executeUpdate();
		session.getTransaction().commit();
		session.close();
		
		if (avator != null && avator_previous != null) {
			//判断用户头像是否修改
			boolean equals = avator_previous.equals(avator);
			if (!equals) {//如果修改则删除原来的头像
				avator_previous.getFile().delete();
				photoDao.delete(avator_previous);
			}
		}
	}
	@Override
	public void forgotPassword(HttpServletRequest request, User user) {
		String hql = "from PasswordChangedRecord p where p.user=? and p.changed=?";
		PasswordChangedRecord record = (PasswordChangedRecord) passwordChangedRecordDao.find(hql, user, 0);
		
		if (record == null) {
			String path = request.getSession().getServletContext().getRealPath("/jsp/user_change_password.jsp");
			File page = new File(path);
			//保存用户的修改密码申请
			record = new PasswordChangedRecord();
			record.setUser(user);
			record.setPage(request, page);
			Date date = new Date();
			record.setCreatedAt(date);
			record.setUpdatedAt(date);
			passwordChangedRecordDao.save(record);
			MailUtils.sendMail(user.getEmail(), "密码修改", "<a href='" + record.getUrl() + "?id=" + user.getId() + "'>点击此处跳转到修改密码页面</a>");
		}
	}
	
	@Override
	public void changPassword(User user) {
		String hql = "from PasswordChangedRecord p where p.user=? and p.changed=?";
		PasswordChangedRecord record = (PasswordChangedRecord) passwordChangedRecordDao.find(hql, user, 0);
		if (record != null) {//验证密码修改是否有效
			user.setUpdatedAt(new Date());
			//每次修改密码都会更新凭据
			user.setAutoLoginCredential(UUID.randomUUID().toString());
			//修改密码
			userDao.update(user);
			//标记用户已经完成密码修改
			record.setChanged(1);
			//用户完成密码修改之后删除掉该页面
			record.getPage().delete();
			record.setUpdatedAt(new Date());
			passwordChangedRecordDao.update(record);
		}
	}

	@Override
	public User getUser(Integer id) {
		return userDao.get(User.class, id);
	}

	@Override
	public User login(User user) {
		String hql = "from User u where u.username = ? and u.password = ?";
		User login = (User) userDao.find(hql, user.getUsername(), user.getPassword());
		if (login != null) {
			login.setLastLoginTime(new Date());
			userDao.update(login);
		}
		
		return login;
	}
	
	public User autoLogin(String credential) {
		String hql = "from User u where u.autoLoginCredential = ?";
		User user = (User) userDao.find(hql, credential);
		return user;
	}

	@Override
	public List<User> listUser(int offset) {
		return userDao.findAll("from User", offset, 10);
	}

	@Override
	public boolean isUsernameExist(String username) {
		String hql = "select count(*) from User u where u.username = ?";
		long count =  (Long) userDao.find(hql, username);
		if (count == 1) {
			return true;
		}
		
		return false;
	}

	@Override
	public User findUserByUsername(String username) {
		String hql = "from User u where u.username = ?";
		User user = (User) userDao.find(hql, username);
		return user;
	}
	
	@Override
	public void addLabel(User user, Label label) {
		user.getLabels().add(label);
		userDao.update(user);
	}
	
	@Override
	public void removeLabel(User user, Label label) {
		Set<Label> labels = user.getLabels();
		Iterator<Label> iterator = labels.iterator();
		while (iterator.hasNext()) {
			if (iterator.next().equals(label)) {
				iterator.remove();
			}
		}
		userDao.update(user);
	}
	
}
